package ua.eug.robov2.schematic.chips;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

import ua.eug.robov2.ImageProvider;
import ua.eug.robov2.schematic.SheetItem;
import ua.eug.robov2.schematic.SheetMap;
import ua.eug.robov2.utils.Vector2i;

public class ChipActor implements SheetItem, Externalizable {

	private TextureRegion texture;
	public Vector2i pos = new Vector2i();
	public Vector2i mapSize;
	public Chip chip;
	private SheetMap owner;

	public ChipActor() { // for externalizable use only!!!
		
	}
	
	public ChipActor(Chip c) {
		this.chip = c;
		init();
	}
	
	private void init() {
		texture = ImageProvider.FindRegion(chip.name);
		mapSize = new Vector2i(chip.chipMap.map[0].length,chip.chipMap.map.length);
	}
	
	@Override
	public void draw(Batch batch, float x, float y) {
		batch.draw(texture,x,y);
	}

	@Override
	public Vector2i sheetPosition() {
		return pos;
	}
	
	public Vector2i getPinPos(int nPin) {
		if (chip.pinPos.length <= nPin) return null;
		return pos.cpy().add(chip.pinPos[nPin]);
	}

	public SheetMap getMap() {
		return chip.chipMap;
	}
	
	public String getName() {
		return chip.name;
	}
	
	// place chip to sheet 
	public void place(SheetMap sm) {
		if (isFit(sm)) {
			owner = sm;
			for (int i=0; i<mapSize.x; i++)
				for (int j=0; j<mapSize.y; j++) {
					if (chip.chipMap.map[mapSize.y-j-1][i] >= 0) // -1 means free square
						sm.map[j+pos.y][i+pos.x] = chip.chipMap.map[mapSize.y-j-1][i] + chip.chipIndex;
				}
		}
	}
	
	// check if chip fits map borders
	public Boolean isFit(SheetMap m) {
		if (pos.x < 0 || pos.y<0 ||
				pos.x + mapSize.x > m.size.x ||
				pos.y + mapSize.y > m.size.y) return false;
		return true;
	}
	 
	// remove chip from sheet
	public void remove() {
		if (owner == null) return;
		for (int i=0; i<mapSize.x; i++)
			for (int j=0; j<mapSize.y; j++) {
				if (owner.map[j][i] >= 0) // negative means wires
					owner.map[j+pos.y][i+pos.x] = 0;
			}
	}

	public Pin getPin(int i) {
		if (chip.pins.length >= i)
			return chip.pins[i-1];
		return null;
	}

	@Override
	public void readExternal(ObjectInput oin) throws IOException,
			ClassNotFoundException {
		chip = (Chip) oin.readObject();
		pos = (Vector2i) oin.readObject();
		init();
	}

	@Override
	public void writeExternal(ObjectOutput oout) throws IOException {
		// TODO Auto-generated method stub
		oout.writeObject( chip );		
		oout.writeObject( pos );
	}
	
	public String toString() {
		return ("[ Chip "+chip.name+", Index "+chip.chipIndex+", Pos "+pos+" ]");
	}
}
